﻿using Chambills.Present.Core;
using Chambills.Present.Core.NotifyOnChange;
using NUnit.Framework;
using Present.Core.Tests.Extensions;

namespace Present.Core.Tests
{
    [TestFixture]
    public class NotifiableObjectTestCase
    {

        [Test]
        public void ObservableNotificationsCallHandlerWhenPropertyChanges()
        {
            var notifiable = new NotifyMock();
            bool handlerWasCalled = false;
            var subscription = System.ObservableExtensions.Subscribe(notifiable
                .WhenPropertyChanges(n => n.Property1)
                , e => { handlerWasCalled = true; });

            notifiable.Property1 = "New Value";
            Assert.IsTrue(handlerWasCalled);
            subscription.Dispose();
        }

        [Test]
        public void ObservableNotificationsDoNotCallHandlerWhenDifferentPropertyChanges()
        {
            var notifiable = new NotifyMock();
            bool handlerWasCalled = false;
            var subscription = System.ObservableExtensions.Subscribe(notifiable
                .WhenPropertyChanges(n => n.Property1), e => { handlerWasCalled = true; });

            notifiable.Property2 = "New Value";
            Assert.IsFalse(handlerWasCalled);
            subscription.Dispose();
        }



        [Test]
        public void PropertyChangeIsFiredWhenPropertyChanged()
        {
            var notifiable = new NotifyMock();
            notifiable.AssertPropertyOnChangeEventFired(n => n.Property1, () => notifiable.Property1 = "New Value");
        }

        [Test]
        public void DependentPropertyChangeIsFiredWhenPropertyChanged()
        {
            var notifiable = new NotifyMock();
            notifiable.AssertPropertyOnChangeEventFired(n => n.CalculatedField1, () => notifiable.Property1 = "New Value");
        }

        public class NotifyMockBase : NotifiableObject
        {
            private string baseProperty;

            public string BaseProperty
            {
                get { return baseProperty; }
                set
                {
                    baseProperty = value;
                    OnPropertyChanged(() => BaseProperty);
                }
            }
        }

        public class NotifyMock : NotifyMockBase
        {
            private string property1;

            public string Property1
            {
                get { return property1; }
                set
                {
                    property1 = value;
                    OnPropertyChanged(() => Property1);
                }
            }

            private string property2;

            public string Property2
            {
                get { return property2; }
                set
                {
                    property2 = value;
                    OnPropertyChanged(() => Property2);
                }
            }





            [DependsOn("Property1")]
            [DependsOn("BaseProperty")]
            public string CalculatedField1
            {
                get { return property1; }
            }
        }

    }
}